package de.hs_mannheim.vem.ajchat;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.ArrayList;

public abstract class ClientApi extends TcpConnection {
	public interface ClientApiObserver {
		void dataChanged();
	}

	final String								userName;
	String										pendingMessage	= null;
	public final ArrayList<String[]>			list			= new ArrayList<String[]>();
	public final ArrayList<ClientApiObserver>	observers		= new ArrayList<ClientApiObserver>();

	private final SockOp						opLogin			= new SockOp() {
																	@Override
																	public void operateOnSocket(
																			final ObjectOutputStream oos)
																			throws Exception {
																		oos.write(1);
																		oos.writeUTF(userName);
																		oos.writeObject(listenAddress);
																	}
																};

	private final SockOp						opSend			= new SockOp() {
																	@Override
																	public void operateOnSocket(
																			final ObjectOutputStream oos)
																			throws Exception {
																		oos.write(0);
																		oos.writeUTF(userName);
																		oos.writeUTF(pendingMessage);
																	}
																};
	final SocketAddress							listenAddress;

	public ClientApi(final SocketAddress listenAddress, final SocketAddress destinationAddress,
			final String name) {
		super((InetSocketAddress) destinationAddress);
		userName = name;
		this.listenAddress = listenAddress;
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					new ServerApi((InetSocketAddress) listenAddress) {
						@Override
						protected void handleException(final Exception e) {
							ClientApi.this.handleException(e);
						}

						@Override
						protected void receive(final ObjectInputStream ois, final SocketAddress addr)
								throws IOException {
							list.add(new String[] {ois.readUTF(), ois.readUTF()});
							for (final ClientApiObserver observer : observers) {
								observer.dataChanged();
							}
						}
					};
				} catch (final Exception e) {
					handleException(e);
				}
			}
		}, "Listener Thread").start();
		login();
	}

	public synchronized void login() {
		try {
			doSockOp(opLogin);
		} catch (final Exception e) {
			handleException(e);
		}
	}

	public synchronized void send(final String message) {
		try {
			pendingMessage = message;
			doSockOp(opSend);
		} catch (final Exception e) {
			handleException(e);
		}
	}

	protected abstract void handleException(Exception e);
}
